package net.pulseproject.commons.util;

import java.util.Arrays;
import java.util.Map.Entry;

public final class StringPropertyUtil {

	private StringPropertyUtil() {
		// util classes should not be instantiated
	}
	
	/**
	 * @param rawKeyValue e.g.: "xyz=42", wheres 42 will be typed correctly to Integer
	 */
	public static Entry<String, Object> parseRawProperty(final String rawKeyValue) {
		if(rawKeyValue == null) { throw new IllegalArgumentException("rawKeyValue == null"); }
		if(rawKeyValue.isEmpty()) { throw new IllegalArgumentException("rawKeyValue is empty"); }
		
		final String[] keyValue = StringUtil.splitAndTrimElements(rawKeyValue, "=");
		if(keyValue.length != 2) {
			throw new IllegalArgumentException("Invalid key value string [" + rawKeyValue + "]! " +
					"Expected 2 entities, but got " + keyValue.length + "! " +
					"Separated entities were: " + Arrays.toString(keyValue));
		}
		
		final String key = keyValue[0];
		final String rawTypedValue = keyValue[1];
		final Object typedValue = TypeUtil.castString(rawTypedValue);
		return new EntryImpl<String, Object>(key, typedValue);
	}
	
	
	/**
	 * Accessibility set to default to enable tests to access this "private" class :-/
	 */
	static class EntryImpl<K, V> implements Entry<K, V> {
		
		private final K key;
		
		private V value;
		
		public EntryImpl(final K key, final V value) {
			if(key == null) { throw new IllegalArgumentException("key == null"); }
			this.key = key;
			this.value = value;
		}

		@Override
		public final K getKey() {
			return this.key;
		}

		@Override
		public final V getValue() {
			return this.value;
		}

		@Override
		public final V setValue(final V newValue) {
			final V oldValue = this.value;
			this.value = newValue;
			return oldValue;
		}
		
		
		@SuppressWarnings("unchecked")
		@Override
		public final boolean equals(final Object other) {
			if((other instanceof EntryImpl<?, ?>) == false) {
				return false;
			}
			final EntryImpl<K, V> that = (EntryImpl<K, V>) other;
			return this.key.equals(that.key) &&
				   this.value.equals(that.value);
		}
		
		@Override
		public final int hashCode() {
			return this.key.hashCode();
		}
	}
}
